﻿using System;
using System.Linq;

using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;

namespace Common {
    public class ZipHelper {
        /// <summary>  
        ///  压缩多个文件  
        /// </summary>  
        /// <param name="files">文件名</param>  
        /// <param name="ZipedFileName">压缩包文件名</param>  
        /// <param name="Password">解压码</param>  
        /// <returns></returns>  
        public static void Zip(string[] files,string ZipedFileName,string Password) {
            files = files.Where(f => File.Exists(f)).ToArray();
            if(files.Length == 0)
                throw new FileNotFoundException("未找到指定打包的文件");
            ZipOutputStream s = new ZipOutputStream(File.Create(ZipedFileName));
            s.SetLevel(6);
            if(!string.IsNullOrEmpty(Password.Trim()))
                s.Password = Password.Trim();
            ZipFileDictory(files,s);
            s.Finish();
            s.Close();
        }

        /// <summary>  
        ///  压缩多个文件  
        /// </summary>  
        /// <param name="files">文件名</param>  
        /// <param name="ZipedFileName">压缩包文件名</param>  
        /// <returns></returns>  
        public static void Zip(string[] files,string ZipedFileName) {
            Zip(files,ZipedFileName,string.Empty);
        }

        private static void ZipFileDictory(string[] files,ZipOutputStream s) {
            ZipEntry entry = null;
            FileStream fs = null;
            Crc32 crc = new Crc32();
            try {
                //创建当前文件夹  
                entry = new ZipEntry("/");  //加上 “/” 才会当成是文件夹创建  
                s.PutNextEntry(entry);
                s.Flush();
                foreach(string file in files) {
                    //打开压缩文件  
                    fs = File.OpenRead(file);

                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer,0,buffer.Length);
                    entry = new ZipEntry("/" + Path.GetFileName(file));
                    entry.DateTime = DateTime.Now;
                    entry.Size = fs.Length;
                    fs.Close();
                    crc.Reset();
                    crc.Update(buffer);
                    entry.Crc = crc.Value;
                    s.PutNextEntry(entry);
                    s.Write(buffer,0,buffer.Length);
                }
            } finally {
                if(fs != null) {
                    fs.Close();
                    fs = null;
                }
                if(entry != null)
                    entry = null;
                GC.Collect();
            }
        }

        public static long DirSize(DirectoryInfo d) {
            long Size = 0;
            // 所有文件大小.
            FileInfo[] fis = d.GetFiles("*.txt");
            foreach(FileInfo fi in fis) {
                Size += fi.Length;
            }
            // 遍历出当前目录的所有文件夹.
            DirectoryInfo[] dis = d.GetDirectories();
            foreach(DirectoryInfo di in dis) {
                Size += DirSize(di);   //这就用到递归了，调用父方法,注意，这里并不是直接返回值，而是调用父返回来的
            }
            return (Size);
        }

        public static string[] GetfilePaths(DirectoryInfo d)
        {
            FileInfo[] fis = d.GetFiles("*.txt");
            string[] filePaths = new string[fis.Length];
            for (int i = 0; i < fis.Length; i++)
            {
                filePaths[i] = fis[i].FullName;
            }
            return filePaths;
        }
    }
}
